﻿/*
 * DATAFLOW CORE
 * 
Copyright 2012 - Mindstorm Multitouch Limited

Author - Bertrand Nouvel

DataFlowCore is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

DataFlowCore is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser Public License for more details.
*/


using MongoDB.Bson;
using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Linq;



namespace DFlowCore
{
    public partial class Engine : MarshalByRefObject
    {
        [AutoServerCommand("nodetypes_list")]
        public IEnumerable<string> NodeTypesList()
        {
            return nodetypes.Keys;
        }



        [AutoServerCommand("nodetype_get_parameters_meta2")]
        public List<BsonDocument> NodeTypesGetParametersMeta2(string nodetypename)
        {
            System.Type t = nodetypes[nodetypename];
            List<BsonDocument> res = new List<BsonDocument>();

            if (t.GetNestedType("Parameters") != null)
            {
                foreach (System.Reflection.FieldInfo fi in t.GetNestedType("Parameters").GetFields())
                {
                    BsonDocument bd = new BsonDocument();
                    bd.Add("name", fi.Name);
                    bd.Add("type", DFlowCore.BsonUtils.TranslateTypeInfo(fi.FieldType));
                    res.Add(bd);
                }
            }
            return res;
        }




        [ServerCommand("nodetype_get_parameters_meta")]
        public BsonDocument NodeTypesGetParametersMeta(BsonDocument q)
        {
            System.Type t = null;
            try
            {
                t = nodetypes[q["nodetypename"].AsString];
            }
            catch (KeyNotFoundException knf)
            {
                return new BsonDocument("error", knf.ToString());
            }

            List<BsonValue> res = new List<BsonValue>();
            //t.type

            if (t.GetNestedType("Parameters") != null)
            {
                foreach (System.Reflection.FieldInfo fi in t.GetNestedType("Parameters").GetFields())
                {
                    res.Add(new BsonArray(new BsonValue[] { new BsonString(DFlowCore.BsonUtils.TranslateTypeInfo(fi.FieldType)), new BsonString(fi.Name) }));
                }
            }
            return new BsonDocument("res", new BsonDocument("args", new BsonArray(res)));
        }




        [ServerCommand("nodetype_get_input_meta2")]
        public List<BsonDocument> NodeTypesGetInputMeta2(string nodetypename)
        {
            System.Type t = nodetypes[nodetypename];

            List<BsonDocument> res = new List<BsonDocument>();

            foreach (System.Reflection.FieldInfo fi in t.GetFields())
            {
                if (fi.GetCustomAttributes(typeof(DFlow.InputPin), false).Length != 0)
                {
                    BsonDocument bd = new BsonDocument();
                    bd.Add("name", fi.Name);
                    bd.Add("type", DFlowCore.BsonUtils.TranslateTypeInfo(fi));
                    res.Add(bd);
                }
            }
            return res;//new BsonDocument("res", new BsonArray(res));
        }




        [ServerCommand("nodetype_get_input_meta")]
        public BsonDocument NodeTypesGetInputMeta(BsonDocument q)
        {
            System.Type t = null;
            try
            {
                t = nodetypes[q["nodetypename"].AsString];
            }
            catch (KeyNotFoundException knf)
            {
                return new BsonDocument("error", knf.ToString());
            }
            List<BsonValue> res = new List<BsonValue>();

            foreach (System.Reflection.FieldInfo fi in t.GetFields())
            {
                if (fi.GetCustomAttributes(typeof(DFlow.InputPin), false).Length != 0)
                {
                    res.Add(new BsonArray(new BsonValue[] { new BsonString(DFlowCore.BsonUtils.TranslateTypeInfo(fi)), new BsonString(fi.Name) }));
                }
            }
            return new BsonDocument("res", new BsonDocument("pins", new BsonArray(res)));
        }




        [AutoServerCommand("nodetype_get_output_meta2")]
        public List<BsonDocument> NodeTypesGetOutputMeta2(string nodetypename)
        {
            System.Type t = null;

            t = nodetypes[nodetypename];
            List<BsonDocument> res = new List<BsonDocument>();

            foreach (System.Reflection.FieldInfo fi in t.GetFields())
            {
                if (fi.GetCustomAttributes(typeof(DFlow.OutputPin), false).Length != 0)
                {
                    BsonDocument bd = new BsonDocument();
                    bd.Add("name", fi.Name);
                    bd.Add("type", DFlowCore.BsonUtils.TranslateTypeInfo(fi));
                    res.Add(bd);
                }
            }
            return res;
        }


        [ServerCommand("nodetype_get_output_meta")]
        public BsonDocument NodeTypesGetOutputMeta(BsonDocument q)
        {
            System.Type t = null;
            try
            {
                t = nodetypes[q["nodetypename"].AsString];
            }
            catch (KeyNotFoundException knf)
            {
                return new BsonDocument("error", knf.ToString());
            }
            List<BsonValue> res = new List<BsonValue>();

            foreach (System.Reflection.FieldInfo fi in t.GetFields())
            {
                if (fi.GetCustomAttributes(typeof(DFlow.OutputPin), false).Length != 0)
                {
                    res.Add(new BsonArray(new BsonValue[] { new BsonString(DFlowCore.BsonUtils.TranslateTypeInfo(fi)), new BsonString(fi.Name) }));
                }
            }
            return new BsonDocument("res", new BsonDocument("pins", new BsonArray(res)));
        }

        /// <summary>
        /// Returns cross platform metadata about the node.
        /// </summary>        
        /// <returns></returns>
        [ServerCommand("nodetype_get_meta")]
        public BsonDocument NodeTypesGetMeta(BsonDocument q)
        {
            System.Type t = null;
            try
            {
                t = nodetypes[q["nodetypename"].AsString];
            }
            catch (KeyNotFoundException knf)
            {
                return new BsonDocument("error", knf.ToString());
            }

            BsonDocument bd = new BsonDocument();
            bd.Add("name", t.Name);
            bd.Add("author", ((t.Assembly.GetCustomAttributes(typeof(System.Reflection.AssemblyCompanyAttribute), false)[0]) as System.Reflection.AssemblyCompanyAttribute).Company);
            //XmlElement documentation = DFlowCore.DocsByReflection.XMLFromMember(typeof(SomeExampleClass).GetProperty("ExampleProperty"));
            //Console.WriteLine(documentation["summary"].InnerText.Trim());


            return new BsonDocument("res", bd);
        }

    }
}